﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Qiniu.Conf;
using Qiniu.RSF;
using Qiniu.RS;
using Qiniu.RPC;
using Qiniu.IO.Resumable;
using System.IO;
using System.Net;
using System.ComponentModel;

namespace qiniuUI
{
    class qiniuOperation
    {
        public static string name_string;
        public static long file_size;
        public qiniuOperation(string ak, string sk)
        {
            Config.ACCESS_KEY = ak;
            Config.SECRET_KEY = sk;
        }
        public void list(string bucket, List<string> lst)
        {
            RSFClient rsf = new RSFClient(bucket);
            rsf.Prefix = "";
            rsf.Limit = 100;
            List<DumpItem> items;
            while ((items = rsf.Next()) != null)
            {
                foreach (DumpItem i in items)
                {
                    lst.Add(i.Key);
                }
            }
        }
        public void stat(string bucket, string key, List<string> lst)
        {
            RSClient client = new RSClient();
            Entry entry = client.Stat(new EntryPath(bucket, key));
            if (entry.OK)
            {
                lst.Add(entry.Hash);
                lst.Add(entry.PutTime + "");
                lst.Add(entry.Fsize + "");
                lst.Add(entry.MimeType + "");
            }
        }
        public void set_selected_items(List<string> lst, string str)
        {
            lst.Add(str);
        }
        public void except_process(Exception except)
        {
            string code;
            int code_index = 0;
            Match code_status;
            Regex r = new Regex("\\([0-9]*\\)");
            Regex r1 = new Regex("\\d{1,3}");
            code = except.ToString();
            if (code != null)
            {
                code_status = r.Match(code);
                code_status = r1.Match(code_status.ToString());
                try
                {
                    code_index = int.Parse(code_status.ToString());
                }
                catch (Exception e)
                {
                    MessageBox.Show("文件名字不正确." + e.ToString());
                }
            }
            switch (code_index)
            {
                case 631:
                    MessageBox.Show("你输入的bucket不存在。");
                    break;
                case 401:
                    MessageBox.Show("获取权限不足。");
                    break;
                default:
                    MessageBox.Show("未知错误代码:" + code_index);
                    break;

            }
        }

        private void Dispose()
        {
            throw new NotImplementedException();
        }
        public string batch_stat(string bucket, List<string> keys)
        {
            RSClient client = new RSClient();
            Int64 sum = 0;
            List<EntryPath> entrypaths = new List<EntryPath>();
            List<BatchRetItem> batchretitem = new List<BatchRetItem>();
            foreach (string key in keys)
            {
                entrypaths.Add(new EntryPath(bucket, key));
            }
            batchretitem = client.BatchStat(entrypaths.ToArray());
            foreach (BatchRetItem i in batchretitem)
            {
                sum += i.data.FSize;
            }
            return ("" + sum);
        }
        public void batch_del(string bucket, List<string> keys)
        {
            RSClient client = new RSClient();
            List<EntryPath> entrypaths = new List<EntryPath>();
            foreach (string key in keys)
            {
                entrypaths.Add(new EntryPath(bucket, key));
            }
            client.BatchDelete(entrypaths.ToArray());

        }
        public void delete(string bucket, string key)
        {
            RSClient client = new RSClient();
            CallRet ret = client.Delete(new EntryPath(bucket, key));
        }
        public void batch_mov(string bucket, List<string> keys, List<string> changename, string prefix = "", bool source_name_rule = false, bool num_rule = false, string postfix = "")
        {
            int i = 0;
            string dest_key = "";
            List<EntryPathPair> pairs = new List<EntryPathPair>();
            foreach (string key in keys)
            {
                if (num_rule)
                {
                    dest_key = prefix + i + postfix;
                    i++;
                }
                else if (source_name_rule)
                {
                    Regex r = new Regex("/.+?$");
                    dest_key = r.Match(key).ToString();
                    if (dest_key == "")
                    {
                        dest_key = key;
                    }
                    else
                    {
                        dest_key = dest_key.Replace("/", "");
                    }
                    dest_key = prefix + dest_key + postfix;
                }
                else
                {
                    dest_key = prefix + Guid.NewGuid().ToString() + postfix;
                }
                changename.Add(dest_key);
                EntryPathPair entry = new EntryPathPair(bucket, key, dest_key);
                pairs.Add(entry);
            }
            RSClient client = new RSClient();
            client.BatchMove(pairs.ToArray());
        }
        public void batch_copy(string bucket, List<string> keys, List<string> changename, string prefix = "", bool source_name_rule = false, bool num_rule = false, string postfix = "")
        {
            int i = 0;
            string dest_key = "";
            List<EntryPathPair> pairs = new List<EntryPathPair>();
            foreach (string key in keys)
            {
                if (num_rule)
                {
                    dest_key = prefix + i + postfix;
                    i++;
                }
                else if (source_name_rule)
                {
                    Regex r = new Regex("/.+?$");
                    dest_key = r.Match(key).ToString();
                    if (dest_key == "")
                    {
                        dest_key = key;
                    }
                    else
                    {
                        dest_key = dest_key.Replace("/", "");
                    }
                    dest_key = prefix + dest_key + postfix;
                }
                else
                {
                    dest_key = prefix + Guid.NewGuid().ToString() + postfix;
                }
                changename.Add(dest_key);
                EntryPathPair entry = new EntryPathPair(bucket, key, dest_key);
                pairs.Add(entry);
            }
            RSClient client = new RSClient();
            client.BatchCopy(pairs.ToArray());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="srcEncoding">原编码</param>
        /// <param name="dstEncoding">目标编码</param>
        /// <param name="srcBytes">原</param>
        public void OutputByEncoding(Encoding srcEncoding, Encoding dstEncoding, string[] srcStr, List<string> dstStr)
        {
            foreach (string i in srcStr)
            {
                byte[] srcBytes = srcEncoding.GetBytes(i);
                string a = srcEncoding.GetString(srcBytes);
                byte[] bytes = Encoding.Convert(srcEncoding, dstEncoding, srcBytes);
                dstStr.Add(dstEncoding.GetString(bytes));
            }
        }
        public void ResumablePutFile(string bucket, List<string> keys, List<string> changename, string prefix = "", bool source_name_rule = false, bool num_rule = false, string postfix = "")
        {
            PutPolicy policy = new PutPolicy(bucket, 3600);
            string upToken = policy.Token();
            Settings setting = new Settings();
            int i = 0;
            string dest_key = "";
            List<EntryPathPair> pairs = new List<EntryPathPair>();
            foreach (string key in keys)
            {
                if (num_rule)
                {
                    dest_key = prefix + i + postfix;
                    i++;
                }
                else if (source_name_rule)
                {
                    Regex r = new Regex(@"^(?<fpath>([a-zA-Z]:\\)([\s\.\-\w]+\\)*)(?<fname>[\w]+)(?<namext>(\.[\w]+)*)(?<suffix>\.[\w]+)");
                    Match result = r.Match(key);
                    dest_key = result.Result("${fname}") + result.Result("${namext}") + result.Result("${suffix}");
                    if (dest_key == "")
                    {
                        dest_key = key;
                    }
                    dest_key = prefix + dest_key + postfix;
                }
                else
                {
                    dest_key = prefix + Guid.NewGuid().ToString() + postfix;
                }
                changename.Add(dest_key);
                ResumablePutExtra extra = new ResumablePutExtra();
                extra.Notify += this.showNotify;
                extra.NotifyErr += this.showNotifyErr;
                Console.Clear();
                Console.WriteLine("uploading------>\n\r");
                Console.WriteLine(key + "\n\r");
                qiniuOperation.name_string = key;
                FileStream fs = File.OpenRead(key);
                qiniuOperation.file_size = fs.Length;
                ResumablePut client = new ResumablePut(setting, extra);
                client.PutFile(upToken, key, dest_key);
            }
        }
        private void showNotify(object sender, PutNotifyEvent e)
        {
            Console.Clear();
            Console.WriteLine("上传的文件是" + qiniuOperation.name_string);
            if (qiniuOperation.file_size <= 4 * 1024 * 1024)
            {
                Console.WriteLine("进度是100%");
                Console.WriteLine("上传的大小" + qiniuOperation.file_size);
            }
            else
            {
                if ((qiniuOperation.file_size / (4 * 1024 * 1024) - 1) >= e.BlkIdx)
                {
                    Console.WriteLine("进度是" + ((e.BlkIdx + 1) * 1024 * 1024 * 4 * 100) / qiniuOperation.file_size + "%");
                }
                else
                {
                    Console.WriteLine("进度是100%");
                    Console.WriteLine("上传的大小" + qiniuOperation.file_size);
                }
            }
        }
        private void showNotifyErr(object sender, PutNotifyErrorEvent e)
        {
        }
        public void copy(string bucket, List<string> keys, string bucket_dst, List<string> changename, string prefix = "", bool source_name_rule = false, bool num_rule = false, string postfix = "")
        {
            RSClient client = new RSClient();
            int i = 0;
            string dest_key = "";
            foreach (string key in keys)
            {
                if (num_rule)
                {
                    dest_key = prefix + i + postfix;
                    i++;
                }
                else if (source_name_rule)
                {
                    Regex r = new Regex("/.+?$");
                    dest_key = r.Match(key).ToString();
                    if (dest_key == "")
                    {
                        dest_key = key;
                    }
                    else
                    {
                        dest_key = dest_key.Replace("/", "");
                    }
                    dest_key = prefix + dest_key + postfix;
                }
                else
                {
                    dest_key = prefix + Guid.NewGuid().ToString() + postfix;
                }
                changename.Add(dest_key);
                client.Copy(new EntryPathPair(bucket, key, bucket_dst, dest_key));
            }
        }
        public void move(string bucket, List<string> keys, string bucket_dst, List<string> changename, string prefix = "", bool source_name_rule = false, bool num_rule = false, string postfix = "")
        {
            RSClient client = new RSClient();
            int i = 0;
            string dest_key = "";
            foreach (string key in keys)
            {
                if (num_rule)
                {
                    dest_key = prefix + i + postfix;
                    i++;
                }
                else if (source_name_rule)
                {
                    Regex r = new Regex("/.+?$");
                    dest_key = r.Match(key).ToString();
                    if (dest_key == "")
                    {
                        dest_key = key;
                    }
                    else
                    {
                        dest_key = dest_key.Replace("/", "");
                    }
                    dest_key = prefix + dest_key + postfix;
                }
                else
                {
                    dest_key = prefix + Guid.NewGuid().ToString() + postfix;
                }
                changename.Add(dest_key);
                new EntryPathPair(bucket, key, bucket_dst, dest_key);
                client.Move(new EntryPathPair(bucket, key, bucket_dst, dest_key));
            }
        }
    }
}
